package bupt.xixi.learning.beans.factory.support;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import bupt.xixi.learning.beans.BeansException;
import bupt.xixi.learning.beans.factory.FactoryBean;

public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry{

    private static final Object NULL_OBJECT = new Object();

    private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>();


    protected Object getCacheObjectForFactoryBean(String beanName) {
        Object object = this.factoryBeanObjectCache.get(beanName);
        return (object != NULL_OBJECT? object: null);
    }

    protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName) {
        if (factory.isSingleton()) {
            Object object = this.factoryBeanObjectCache.get(beanName);
            if (object == null) {
                object = doGetObjectFromFactoryBean(factory, beanName);
                this.factoryBeanObjectCache.put(beanName, object != null ? object : NULL_OBJECT);
            }
            return object != NULL_OBJECT ? object : null;
        }
        return doGetObjectFromFactoryBean(factory, beanName);
        

    }

    private Object doGetObjectFromFactoryBean(FactoryBean factory, String beanName) {
        try {
            return factory.getObject();
        } catch (Exception e) {
            throw new BeansException(String.format("FactoryBean threw exception on object [%s] creation", beanName), e);
        }
    }

}